package cn.com.tarotframework.utils.response;

import io.swagger.v3.oas.annotations.media.Schema;

import java.io.Serial;
import java.io.Serializable;

/**
 * copyright (C), 2022, 塔罗牌基础架构
 * @program: tarot-utils
 * @description: 响应结果实体类
 * @author: xincan
 * @date: 2022/05/20 16:44
 * @version: 0.0.1-SNAPSHOT
 */
@Schema(name = "响应结果", description = "响应结果")
public class TarotResult<T> implements Serializable {

    @Serial
    private static final long serialVersionUID = -3814345588802235618L;

    @Schema(name = "code", type = "int", description = "响应结果编码", defaultValue = "200")
    private Integer code;

    @Schema(name = "msg", type = "int", description = "响应结果信息", defaultValue = "操作成功")
    private String msg;

    @Schema(name = "count", type = "long", description = "分页总数", defaultValue = "111")
    private long count;

    @Schema(name = "data", type = "object", description = "分页总数", defaultValue = "111")
    private T data;

    @Schema(name = "count", type = "long", description = "操作时间")
    private long time = System.currentTimeMillis();

    public TarotResult() {}

    public TarotResult(TarotCode responseCode) {
        this.code = responseCode.code();
        this.msg = responseCode.message();
    }

    public TarotResult(TarotCode responseCode, long count, T data) {
        this.code = responseCode.code();
        this.msg = responseCode.message();
        this.count = count;
        this.data = data;
    }

    /**
     * @description: 返回处理结果： 针对于返回业务处理之后，无需通知前端具体处理信息，走系统默认的提示信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success() {
        return new TarotResult<T>(TarotCode.REQUEST_SUCCESS);
    }

    /**
     * @description: 返回处理结果： 针对于返回业务处理之后，需要向前端反馈后台处理的数据，将其返回
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param responseCode  <TarotCode>   响应状态
     * @param data     <T>      响应数据
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(TarotCode responseCode, T data) {
        return new TarotResult<T>(responseCode)
                .count(1)
                .data(data);
    }

    /**
     * @description: 返回处理结果： 针对于返回业务处理之后，需要向前端反馈后台处理的数据，将其返回
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param data  <T>    响应数据
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(T data) {
        return new TarotResult<T>(TarotCode.REQUEST_SUCCESS)
                .count(1)
                .data(data);
    }

    /**
     * @description: 返回处理结果： 针对于返回业务处理之后，需要向前端反馈后台处理的数据，并且将处理结果描述提供给前端
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param data      响应数据
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(String message, T data) {
        return new TarotResult<T>()
                .code(TarotCode.REQUEST_SUCCESS)
                .msg(message)
                .count(1)
                .data(data);
    }

    /**
     * @description: 返回处理结果：
     * （数据分页）针对于返回业务处理之后，需要向前端反馈后台处理分页的数据，
     *  并携带状态、数据总条数、系统默认处理信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param data      响应数据
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(long count, T data){
        return new TarotResult<T>(TarotCode.REQUEST_SUCCESS)
                .count(count)
                .data(data);
    }

    /**
     * @description: 返回处理结果：
     * （数据分页）针对于返回业务处理之后，需要向前端反馈后台处理分页的数据，
     *  并携带状态、数据总条数、自定义处理信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param message   响应结果信息
     * @param count     响应数据条数
     * @param data      响应数据
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(String message, long count, T data){
        return new TarotResult<T>()
                .code(TarotCode.REQUEST_SUCCESS)
                .msg(message)
                .count(count)
                .data(data);
    }

    /**
     * @description: 返回处理结果
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param code      响应结果编码
     * @param message   响应结果信息
     * @param data      响应数据
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(int code, String message, T data){
        return new TarotResult<T>()
                .code(code)
                .msg(message)
                .count(0)
                .data(data);
    }

    /**
     * @description: 返回处理结果
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param code      响应结果编码
     * @param message   响应结果信息
     * @param data      响应数据
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(int code, String message, long count, T data){
        return new TarotResult<T>()
                .code(code)
                .msg(message)
                .count(count)
                .data(data);
    }

    /**
     * @description: 返回处理结果：针对于返回业务处理之后，需要向前端反馈后台处理的数据，将其返回
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param responseCode   响应状态
     * @param count          响应数据条数
     * @param data           响应数据
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> success(TarotCode responseCode, long count, T data) {
        return new TarotResult<T>(responseCode)
                .count(count)
                .data(data);
    }

    /**
     * @description: 返回处理结果：针对于系统业务处理失败之后，系统默认返回失败处理信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> error() {
        return new TarotResult<T>(TarotCode.REQUEST_ERROR)
                .count(0)
                .msg(TarotCode.REQUEST_ERROR.message())
                .data(null);
    }

    /**
     * @description: 返回处理结果：针对于系统业务处理失败之后，系统默认返回失败处理信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param responseCode   响应状态
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> error(TarotCode responseCode) {
        return new TarotResult<T>(responseCode)
                .count(0)
                .msg(responseCode.message())
                .data(null);
    }

    /**
     * @description: 返回处理结果：针对于系统业务处理失败之后，系统默认返回失败处理信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param responseCode   响应状态
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> error(TarotCode responseCode, T data) {
        return new TarotResult<T>(responseCode)
                .count(0)
                .data(data);
    }

    /**
     * @description: 返回处理结果：针对于系统业务处理失败之后，系统默返回自定义失败处理信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param message   响应结果信息
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> error(String message) {
        return new TarotResult<T>()
                .code(TarotCode.REQUEST_ERROR)
                .msg(message)
                .count(0)
                .data(null);
    }

    /**
     * @description: 返回处理结果：针对于系统业务处理失败之后，系统默返回自定义失败处理信息并返回传入修改的信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param message   响应结果信息
     * @param data      响应数据
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> error(String message, T data) {
        return new TarotResult<T>()
                .code(TarotCode.REQUEST_ERROR)
                .msg(message)
                .count(0)
                .data(data);
    }

    /**
     * @description: 返回处理结果：针对于系统业务处理失败之后，系统默返回自定义失败处理信息并返回传入修改的信息
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param code      响应结果编码
     * @param message   响应结果信息
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> error(Integer code, String message) {
        return new TarotResult<T>()
                .code(code)
                .msg(message)
                .count(0)
                .data(null);
    }

    /**
     * @description: 返回处理结果：token过期传入code,或其他的错误传入code值
     * @author: xincan
     * @date: 2022/5/17 10:49
     * @param code      响应结果编码
     * @param message   响应结果信息
     * @param data      响应数据
     * @param <T>       响应数据类型
     * @return: ResponseObject<T>
     **/
    public static <T> TarotResult<T> error(Integer code, String message, T data) {
        return new TarotResult<T>()
                .code(code)
                .msg(message)
                .count(0)
                .data(data);
    }

    public TarotResult<T> code(TarotCode responseCode) {
        this.code = responseCode.code();
        this.msg = responseCode.message();
        return this;
    }

    public TarotResult<T> code(int code) {
        this.code = code;
        return this;
    }


    public TarotResult<T> msg(String msg) {
        this.msg = msg;
        return this;
    }

    public TarotResult<T> count(long count) {
        this.count = count;
        return this;
    }

    public TarotResult<T> data(T data) {
        this.data = data;
        return this;
    }

    public TarotResult<T> time(long time) {
        this.time = time;
        return this;
    }

    public int getCode() {
        return code;
    }

    public String getMsg() {
        return msg;
    }

    public long getCount() {
        return count;
    }

    public T getData() {
        return data;
    }

    public long getTime() {
        return time;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    public void setCount(long count) {
        this.count = count;
    }

    public void setData(T data) {
        this.data = data;
    }

    public void setTime(long time) {
        this.time = time;
    }

    @Override
    public String toString() {
        return "TarotResult{" +
                "code=" + code +
                ", msg='" + msg + '\'' +
                ", count=" + count +
                ", data=" + data +
                ", time=" + time +
                '}';
    }
}
